home *** CD-ROM | disk | FTP | other *** search
- /* Generic Objects and Functions.
- Copyright (C) 1995 Amdahl Corporation.
- Copyright (C) 1995 Board of Trustees, University of Illinois
- Copyright (C) 1995 Ben Wing
-
- This file is part of XEmacs.
-
- XEmacs is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- XEmacs is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- for more details.
-
- You should have received a copy of the GNU General Public License
- along with XEmacs; see the file COPYING. If not, write to the Free
- Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- #include <config.h>
- #include "lisp.h"
-
- #include "device.h"
- #include "elhash.h"
- #include "faces.h"
- #include "frame.h"
- #include "objects.h"
- #include "specifier.h"
- #include "window.h"
-
- /* Authors: Ben Wing, Chuck Thompson */
-
- void
- finalose (void *ptr)
- {
- Lisp_Object obj;
- XSETOBJ (obj, Lisp_Record, ptr);
-
- signal_simple_error
- ("Can't dump an emacs containing window system objects", obj);
- }
-
-
- /****************************************************************************
- * Color-Instance Object *
- ****************************************************************************/
-
- Lisp_Object Qcolor_instancep;
- static Lisp_Object mark_color_instance (Lisp_Object, void (*) (Lisp_Object));
- static void print_color_instance (Lisp_Object, Lisp_Object, int);
- static void finalize_color_instance (void *, int);
- static int color_instance_equal (Lisp_Object, Lisp_Object, int depth);
- static unsigned long color_instance_hash (Lisp_Object obj, int depth);
- DEFINE_LRECORD_IMPLEMENTATION ("color-instance", color_instance,
- mark_color_instance, print_color_instance,
- finalize_color_instance, color_instance_equal,
- color_instance_hash,
- struct Lisp_Color_Instance);
-
- static Lisp_Object
- mark_color_instance (Lisp_Object obj, void (*markobj) (Lisp_Object))
- {
- struct Lisp_Color_Instance *c = XCOLOR_INSTANCE (obj);
- ((markobj) (c->name));
- MAYBE_DEVMETH (XDEVICE (c->device), mark_color_instance, (c, markobj));
-
- return (c->device);
- }
-
- static void
- print_color_instance (Lisp_Object obj, Lisp_Object printcharfun,
- int escapeflag)
- {
- char buf[100];
- struct Lisp_Color_Instance *c = XCOLOR_INSTANCE (obj);
- if (print_readably)
- error ("printing unreadable object #<color-instance 0x%x>",
- c->header.uid);
- write_c_string ("#<color-instance ", printcharfun);
- print_internal (c->name, printcharfun, 0);
- write_c_string (" on ", printcharfun);
- print_internal (c->device, printcharfun, 0);
- MAYBE_DEVMETH (XDEVICE (c->device), print_color_instance,
- (c, printcharfun, escapeflag));
- sprintf (buf, " 0x%x>", c->header.uid);
- write_c_string (buf, printcharfun);
- }
-
- static void
- finalize_color_instance (void *header, int for_disksave)
- {
- struct Lisp_Color_Instance *c = (struct Lisp_Color_Instance *) header;
-
- if (for_disksave) finalose (c);
-
- MAYBE_DEVMETH (XDEVICE (c->device), finalize_color_instance, (c));
- }
-
- static int
- color_instance_equal (Lisp_Object o1, Lisp_Object o2, int depth)
- {
- struct Lisp_Color_Instance *c1 = XCOLOR_INSTANCE (o1);
- struct Lisp_Color_Instance *c2 = XCOLOR_INSTANCE (o2);
- struct device *d1 = XDEVICE (c1->device);
- struct device *d2 = XDEVICE (c2->device);
-
- if (d1 != d2)
- return 0;
-
- if (!HAS_DEVMETH_P (d1, color_instance_equal))
- return EQ (o1, o2);
- return DEVMETH (d1, color_instance_equal, (c1, c2, depth));
- }
-
- static unsigned long
- color_instance_hash (Lisp_Object obj, int depth)
- {
- struct Lisp_Color_Instance *c = XCOLOR_INSTANCE (obj);
- struct device *d = XDEVICE (c->device);
-
- return HASH2 ((unsigned long) d,
- DEVMETH_OR_GIVEN (d, color_instance_hash, (c, depth),
- LISP_HASH (obj)));
- }
-
- DEFUN ("make-color-instance", Fmake_color_instance, Smake_color_instance,
- 1, 3, 0,
- "Creates a new `color-instance' object of the specified color.\n\
- DEVICE specifies the device this object applies to and defaults to the\n\
- selected device. An error is signalled if the color is unknown or cannot\n\
- be allocated; however, if NOERROR is non-nil, nil is simply returned in\n\
- this case.\n\
- \n\
- The returned object is a normal, first-class lisp object. The way you\n\
- `deallocate' the color is the way you deallocate any other lisp object:\n\
- you drop all pointers to it and allow it to be garbage collected. When\n\
- these objects are GCed, the underlying window-system data (e.g. X object)\n\
- is deallocated as well.")
- (name, device, no_error)
- Lisp_Object name, device, no_error;
- {
- struct Lisp_Color_Instance *c;
- Lisp_Object val;
- int retval = 0;
-
- CHECK_STRING (name, 0);
- XSETDEVICE (device, get_device (device));
-
- c = alloc_lcrecord (sizeof (struct Lisp_Color_Instance),
- lrecord_color_instance);
- c->name = name;
- c->device = device;
-
- c->data = 0;
-
- retval = MAYBE_INT_DEVMETH (XDEVICE (device), initialize_color_instance,
- (c, name, device, !NILP (no_error)));
-
- if (!retval)
- return Qnil;
-
- XSETCOLOR_INSTANCE (val, c);
- return val;
- }
-
- DEFUN ("color-instance-p", Fcolor_instance_p, Scolor_instance_p, 1, 1, 0,
- "Return non-nil if OBJECT is a color instance.")
- (object)
- Lisp_Object object;
- {
- return (COLOR_INSTANCEP (object) ? Qt : Qnil);
- }
-
- DEFUN ("color-instance-name", Fcolor_instance_name, Scolor_instance_name,
- 1, 1, 0,
- "Return the name used to allocate COLOR-INSTANCE.")
- (color_instance)
- Lisp_Object color_instance;
- {
- CHECK_COLOR_INSTANCE (color_instance, 0);
- return (XCOLOR_INSTANCE (color_instance)->name);
- }
-
- DEFUN ("color-instance-rgb-components", Fcolor_instance_rgb_components,
- Scolor_instance_rgb_components, 1, 1, 0,
- "Return a three element list containing the red, green, and blue\n\
- color components of COLOR-INSTANCE, or nil if unknown.")
- (color_instance)
- Lisp_Object color_instance;
- {
- struct Lisp_Color_Instance *c;
-
- CHECK_COLOR_INSTANCE (color_instance, 0);
- c = XCOLOR_INSTANCE (color_instance);
-
- return MAYBE_LISP_DEVMETH (XDEVICE (c->device),
- color_instance_rgb_components,
- (c));
- }
-
- DEFUN ("valid-color-name-p", Fvalid_color_name_p, Svalid_color_name_p,
- 1, 2, 0,
- "Return true if COLOR names a valid color for the current device.\n\
- \n\
- Valid color names for X are listed in the file /usr/lib/X11/rgb.txt, or\n\
- whatever the equivalent is on your system.\n\
- \n\
- Valid color names for TTY are those which have an ISO 6429 (ANSI) sequence.\n\
- In addition to being a color this may be one of a number of attributes\n\
- such as `blink'.")
- (color, device)
- Lisp_Object color, device;
- {
- struct device *d = get_device (device);
-
- CHECK_STRING (color, 0);
- return MAYBE_INT_DEVMETH (d, valid_color_name_p, (d, color)) ? Qt : Qnil;
- }
-
-
- /***************************************************************************
- * Font-Instance Object *
- ***************************************************************************/
-
- Lisp_Object Qfont_instancep;
- static Lisp_Object mark_font_instance (Lisp_Object, void (*) (Lisp_Object));
- static void print_font_instance (Lisp_Object, Lisp_Object, int);
- static void finalize_font_instance (void *, int);
- static int font_instance_equal (Lisp_Object o1, Lisp_Object o2, int depth);
- static unsigned long font_instance_hash (Lisp_Object obj, int depth);
- DEFINE_LRECORD_IMPLEMENTATION ("font-instance", font_instance,
- mark_font_instance, print_font_instance,
- finalize_font_instance, font_instance_equal,
- font_instance_hash, struct Lisp_Font_Instance);
-
- static Lisp_Object font_instance_truename_internal (Lisp_Object xfont,
- int no_error);
-
- static Lisp_Object
- mark_font_instance (Lisp_Object obj, void (*markobj) (Lisp_Object))
- {
- struct Lisp_Font_Instance *f = XFONT_INSTANCE (obj);
-
- ((markobj) (f->name));
- MAYBE_DEVMETH (XDEVICE (f->device), mark_font_instance, (f, markobj));
-
- return f->device;
- }
-
- static void
- print_font_instance (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
- {
- char buf[200];
- struct Lisp_Font_Instance *f = XFONT_INSTANCE (obj);
- if (print_readably)
- error ("printing unreadable object #<font-instance 0x%x>", f->header.uid);
- write_c_string ("#<font-instance ", printcharfun);
- print_internal (f->name, printcharfun, 0);
- write_c_string (" on ", printcharfun);
- print_internal (f->device, printcharfun, 0);
- MAYBE_DEVMETH (XDEVICE (f->device), print_font_instance,
- (f, printcharfun, escapeflag));
- sprintf (buf, " 0x%x>", f->header.uid);
- write_c_string (buf, printcharfun);
- }
-
- static void
- finalize_font_instance (void *header, int for_disksave)
- {
- struct Lisp_Font_Instance *f = (struct Lisp_Font_Instance *) header;
- struct device *d = XDEVICE (f->device);
-
- if (for_disksave) finalose (f);
-
- MAYBE_DEVMETH (d, finalize_font_instance, (f));
- }
-
- /* Fonts are equal if they resolve to the same name.
- Since we call `font-truename' to do this, and since font-truename is lazy,
- this means the `equal' could cause XListFonts to be run the first time.
- */
- static int
- font_instance_equal (Lisp_Object o1, Lisp_Object o2, int depth)
- {
- /* #### should this be moved into a device method? */
- return (internal_equal (font_instance_truename_internal (o1, 1),
- font_instance_truename_internal (o2, 1),
- depth + 1));
- }
-
- static unsigned long
- font_instance_hash (Lisp_Object obj, int depth)
- {
- return internal_hash (font_instance_truename_internal (obj, 1),
- depth + 1);
- }
-
- DEFUN ("make-font-instance", Fmake_font_instance, Smake_font_instance, 1, 3, 0,
- "Creates a new `font-instance' object of the specified name.\n\
- DEVICE specifies the device this object applies to and defaults to the\n\
- selected device. An error is signalled if the font is unknown or cannot\n\
- be allocated; however, if NOERROR is non-nil, nil is simply returned in\n\
- this case.\n\
- \n\
- The returned object is a normal, first-class lisp object. The way you\n\
- `deallocate' the font is the way you deallocate any other lisp object:\n\
- you drop all pointers to it and allow it to be garbage collected. When\n\
- these objects are GCed, the underlying X data is deallocated as well.")
- (name, device, no_error)
- Lisp_Object name, device, no_error;
- {
- struct Lisp_Font_Instance *f;
- Lisp_Object val;
- int retval = 0;
-
- if (NILP (no_error))
- CHECK_STRING (name, 0);
- else if (!STRINGP (name))
- return Qnil;
-
- XSETDEVICE (device, get_device (device));
-
- f = alloc_lcrecord (sizeof (struct Lisp_Font_Instance),
- lrecord_font_instance);
- f->name = name;
- f->device = device;
-
- f->data = 0;
-
- retval = MAYBE_INT_DEVMETH (XDEVICE (device), initialize_font_instance,
- (f, name, device, !NILP (no_error)));
-
- if (!retval)
- return Qnil;
-
- XSETFONT_INSTANCE (val, f);
- return val;
- }
-
- DEFUN ("font-instance-p", Ffont_instance_p, Sfont_instance_p, 1, 1, 0,
- "Return non-nil if OBJECT is a font instance.")
- (object)
- Lisp_Object object;
- {
- return (FONT_INSTANCEP (object) ? Qt : Qnil);
- }
-
- DEFUN ("font-instance-name", Ffont_instance_name, Sfont_instance_name, 1, 1, 0,
- "Return the name used to allocate FONT-INSTANCE.")
- (font_instance)
- Lisp_Object font_instance;
- {
- CHECK_FONT_INSTANCE (font_instance, 0);
- return (XFONT_INSTANCE (font_instance)->name);
- }
-
- Lisp_Object
- font_instance_truename_internal (Lisp_Object font_instance, int no_error)
- {
- struct Lisp_Font_Instance *f = XFONT_INSTANCE (font_instance);
- return DEVMETH_OR_GIVEN (XDEVICE (f->device), font_instance_truename,
- (f, no_error), f->name);
- }
-
- DEFUN ("font-instance-truename", Ffont_instance_truename,
- Sfont_instance_truename, 1, 1, 0,
- "Return the canonical name of the given font instance.\n\
- Font names are patterns which may match any number of fonts, of which\n\
- the first found is used. This returns an unambiguous name for that font\n\
- (but not necessarily its only unambiguous name).")
- (font_instance)
- Lisp_Object font_instance;
- {
- CHECK_FONT_INSTANCE (font_instance, 0);
- return font_instance_truename_internal (font_instance, 0);
- }
-
- DEFUN ("font-instance-properties", Ffont_instance_properties,
- Sfont_instance_properties, 1, 1, 0,
- "Return the properties (an alist or nil) of FONT-INSTANCE.")
- (font_instance)
- Lisp_Object font_instance;
- {
- struct Lisp_Font_Instance *f;
-
- CHECK_FONT_INSTANCE (font_instance, 0);
- f = XFONT_INSTANCE (font_instance);
-
- return MAYBE_LISP_DEVMETH (XDEVICE (f->device),
- font_instance_properties, (f));
- }
-
- DEFUN ("list-fonts", Flist_fonts, Slist_fonts, 1, 2, 0,
- "Return a list of font names matching the given pattern.\n\
- DEVICE specifies which device to search for names, and defaults to the\n\
- currently selected device.")
- (pattern, device)
- Lisp_Object pattern, device;
- {
- CHECK_STRING (pattern, 0);
- XSETDEVICE (device, get_device (device));
-
- return MAYBE_LISP_DEVMETH (XDEVICE (device), list_fonts, (pattern, device));
- }
-
-
- /****************************************************************************
- Color Object
- ***************************************************************************/
- DEFINE_SPECIFIER_TYPE (color);
- /* Qcolor defined in general.c */
-
- static void
- color_create (Lisp_Object obj)
- {
- struct Lisp_Specifier *color = XCOLOR_SPECIFIER (obj);
-
- COLOR_SPECIFIER_FACE (color) = Qnil;
- COLOR_SPECIFIER_FACE_PROPERTY (color) = Qnil;
- }
-
- static void
- color_mark (Lisp_Object obj, void (*markobj) (Lisp_Object))
- {
- struct Lisp_Specifier *color = XCOLOR_SPECIFIER (obj);
-
- ((markobj) (COLOR_SPECIFIER_FACE (color)));
- ((markobj) (COLOR_SPECIFIER_FACE_PROPERTY (color)));
- }
-
- /* No equal or hash methods; ignore the face the color is based off
- of for `equal' */
-
- static Lisp_Object
- color_instantiate (Lisp_Object specifier, Lisp_Object domain,
- Lisp_Object instantiator, int no_error_or_quit)
- {
- Lisp_Object device = DFW_DEVICE (domain);
- struct device *d = XDEVICE (device);
- Lisp_Object instance;
-
- if (COLOR_INSTANCEP (instantiator))
- {
- /* If we are on the same device then we're done. Otherwise change
- the instantiator to the name used to generate the pixel and let the
- STRINGP case deal with it. */
- if (EQ (device, XCOLOR_INSTANCE (instantiator)->device))
- return instantiator;
- else
- instantiator = Fcolor_instance_name (instantiator);
- }
-
- if (STRINGP (instantiator))
- {
- /* First, look to see if we can retrieve a cached value. */
- instance = Fgethash (instantiator, d->color_instance_cache, Qnil);
- /* Otherwise, make a new one. */
- if (NILP (instance))
- {
- instance = Fmake_color_instance (instantiator, device, Qt);
- if (NILP (instance))
- return Qunbound; /* oops, couldn't allocate */
- Fputhash (instantiator, instance, d->color_instance_cache);
- }
- return instance;
- }
- else if (CONSP (instantiator))
- {
- #if 0
- Lisp_Object *spec_list;
- Lisp_Object ltmp;
- int nargs = XINT (Flength (instantiator));
- int cur_arg;
-
- /* This spec is only valid for tty devices. If we get here and
- the device is not a tty then there is a bug in the internal
- color validation routines. */
- if (!DEVICE_IS_TTY (d))
- abort ();
-
- spec_list = (Lisp_Object *) xmalloc (sizeof (Lisp_Object) * nargs);
- ltmp = instantiator;
- cur_arg = 0;
-
- while (!NILP (ltmp))
- {
- Lisp_Object elt = XCAR (ltmp);
- spec_list[cur_arg++] = elt;
- ltmp = XCDR (ltmp);
- }
-
- ltmp = Ftty_make_color_sequence (nargs, spec_list);
- xfree (spec_list);
- return ltmp;
- #endif
- return Qunbound; /* #### do something about this. */
- }
- else if (VECTORP (instantiator))
- {
- /* #### Need loop detection. */
- assert (XVECTOR (instantiator)->size == 2);
- return (FACE_PROPERTY_INSTANCE
- (Fget_face (vector_data (XVECTOR (instantiator))[0]),
- vector_data (XVECTOR (instantiator))[1], domain, 0));
- }
- else if (NILP (instantiator))
- return Qunbound;
- else
- abort (); /* The spec validation routines are screwed up. */
-
- return Qunbound;
- }
-
- static int
- color_validate (Lisp_Object instantiator, int no_error)
- {
- /* #### signal some explanatory errors when NO_ERROR is nil */
-
- if (COLOR_INSTANCEP (instantiator) || STRINGP (instantiator) ||
- NILP (instantiator))
- return 1;
- else if (VECTORP (instantiator) && XVECTOR (instantiator)->size == 2)
- {
- Lisp_Object face = vector_data (XVECTOR (instantiator))[0];
- Lisp_Object field = vector_data (XVECTOR (instantiator))[1];
-
- if (SYMBOLP (face))
- face = Ffind_face (face);
-
- if (!FACEP (face))
- return 0;
- else if (!EQ (field, Qforeground) && !EQ (field, Qbackground))
- return 0;
-
- return 1;
- }
- else
- return 0;
- }
-
- static void
- color_after_change (Lisp_Object specifier, Lisp_Object locale)
- {
- Lisp_Object face = COLOR_SPECIFIER_FACE (XCOLOR_SPECIFIER (specifier));
- Lisp_Object property =
- COLOR_SPECIFIER_FACE_PROPERTY (XCOLOR_SPECIFIER (specifier));
- if (!NILP (face))
- face_property_was_changed (face, property, locale);
- }
-
- void
- set_color_attached_to (Lisp_Object obj, Lisp_Object face, Lisp_Object property)
- {
- struct Lisp_Specifier *color = XCOLOR_SPECIFIER (obj);
-
- COLOR_SPECIFIER_FACE (color) = face;
- COLOR_SPECIFIER_FACE_PROPERTY (color) = property;
- }
-
- DEFUN ("color-specifier-p", Fcolor_specifier_p, Scolor_specifier_p, 1, 1, 0,
- "Return non-nil if OBJECT is a color specifier.")
- (object)
- Lisp_Object object;
- {
- return (COLOR_SPECIFIERP (object) ? Qt : Qnil);
- }
-
-
- /****************************************************************************
- Font Object
- ***************************************************************************/
- DEFINE_SPECIFIER_TYPE (font);
- /* Qfont defined in general.c */
-
- static void
- font_create (Lisp_Object obj)
- {
- struct Lisp_Specifier *font = XFONT_SPECIFIER (obj);
-
- FONT_SPECIFIER_FACE (font) = Qnil;
- FONT_SPECIFIER_FACE_PROPERTY (font) = Qnil;
- }
-
- static void
- font_mark (Lisp_Object obj, void (*markobj) (Lisp_Object))
- {
- struct Lisp_Specifier *font = XFONT_SPECIFIER (obj);
-
- ((markobj) (FONT_SPECIFIER_FACE (font)));
- ((markobj) (FONT_SPECIFIER_FACE_PROPERTY (font)));
- }
-
- /* No equal or hash methods; ignore the face the font is based off
- of for `equal' */
-
- static Lisp_Object
- font_instantiate (Lisp_Object specifier, Lisp_Object domain,
- Lisp_Object instantiator, int no_error_or_quit)
- {
- Lisp_Object device = DFW_DEVICE (domain);
- struct device *d = XDEVICE (device);
- Lisp_Object instance;
-
- if (FONT_INSTANCEP (instantiator))
- {
- if (EQ (device, XFONT_INSTANCE (instantiator)->device))
- return instantiator;
- else
- instantiator = Ffont_instance_name (instantiator);
- }
- else if (STRINGP (instantiator))
- {
- /* First, look to see if we can retrieve a cached value. */
- instance = Fgethash (instantiator, d->font_instance_cache, Qnil);
- /* Otherwise, make a new one. */
- if (NILP (instance))
- {
- instance = Fmake_font_instance (instantiator, device, Qt);
- if (NILP (instance))
- return Qunbound; /* oops, couldn't allocate */
- Fputhash (instantiator, instance, d->font_instance_cache);
- }
- return instance;
- }
- else if (VECTORP (instantiator))
- {
- /* #### Need loop detection. */
- assert (XVECTOR (instantiator)->size == 1);
- return (FACE_FONT
- (Fget_face (vector_data (XVECTOR (instantiator))[0]), domain));
- }
- else if (NILP (instantiator))
- return Qunbound;
- else
- abort (); /* Eh? */
-
- return Qunbound;
- }
-
- static int
- font_validate (Lisp_Object instantiator, int no_error)
- {
- /* #### signal some explanatory errors when CAN_SIGNAL_ERROR is t */
-
- if (FONT_INSTANCEP (instantiator) || STRINGP (instantiator) ||
- NILP (instantiator))
- return 1;
- else if (VECTORP (instantiator) && XVECTOR (instantiator)->size == 1)
- {
- Lisp_Object face = vector_data (XVECTOR (instantiator))[0];
-
- if (SYMBOLP (face))
- face = Ffind_face (face);
-
- if (!FACEP (face))
- return 0;
-
- return 1;
- }
- else
- return 0;
- }
-
- static void
- font_after_change (Lisp_Object specifier, Lisp_Object locale)
- {
- Lisp_Object face = FONT_SPECIFIER_FACE (XFONT_SPECIFIER (specifier));
- Lisp_Object property =
- FONT_SPECIFIER_FACE_PROPERTY (XFONT_SPECIFIER (specifier));
- if (!NILP (face))
- face_property_was_changed (face, property, locale);
- }
-
- void
- set_font_attached_to (Lisp_Object obj, Lisp_Object face, Lisp_Object property)
- {
- struct Lisp_Specifier *font = XFONT_SPECIFIER (obj);
-
- FONT_SPECIFIER_FACE (font) = face;
- FONT_SPECIFIER_FACE_PROPERTY (font) = property;
- }
-
- DEFUN ("font-specifier-p", Ffont_specifier_p, Sfont_specifier_p, 1, 1, 0,
- "Return non-nil if OBJECT is a font specifier.")
- (object)
- Lisp_Object object;
- {
- return (FONT_SPECIFIERP (object) ? Qt : Qnil);
- }
-
-
- /*****************************************************************************
- Face Boolean Object
- ****************************************************************************/
- DEFINE_SPECIFIER_TYPE (face_boolean);
- Lisp_Object Qface_boolean;
-
- static void
- face_boolean_create (Lisp_Object obj)
- {
- struct Lisp_Specifier *face_boolean = XFACE_BOOLEAN_SPECIFIER (obj);
-
- FACE_BOOLEAN_SPECIFIER_FACE (face_boolean) = Qnil;
- FACE_BOOLEAN_SPECIFIER_FACE_PROPERTY (face_boolean) = Qnil;
- }
-
- static void
- face_boolean_mark (Lisp_Object obj, void (*markobj) (Lisp_Object))
- {
- struct Lisp_Specifier *face_boolean = XFACE_BOOLEAN_SPECIFIER (obj);
-
- ((markobj) (FACE_BOOLEAN_SPECIFIER_FACE (face_boolean)));
- ((markobj) (FACE_BOOLEAN_SPECIFIER_FACE_PROPERTY (face_boolean)));
- }
-
- /* No equal or hash methods; ignore the face the face-boolean is based off
- of for `equal' */
-
- static Lisp_Object
- face_boolean_instantiate (Lisp_Object specifier, Lisp_Object domain,
- Lisp_Object instantiator, int no_error_or_quit)
- {
- /* #### signal some explanatory errors when CAN_SIGNAL_ERROR is t */
-
- if (NILP (instantiator) || EQ (instantiator, Qt))
- return instantiator;
- else if (VECTORP (instantiator))
- {
- Lisp_Object retval;
-
- assert (XVECTOR (instantiator)->size == 2 ||
- XVECTOR (instantiator)->size == 3);
- retval = FACE_PROPERTY_INSTANCE
- (Fget_face (vector_data (XVECTOR (instantiator))[0]),
- vector_data (XVECTOR (instantiator))[1], domain, 0);
-
- if (XVECTOR (instantiator)->size == 3 &&
- !NILP (vector_data (XVECTOR (instantiator))[2]))
- retval = (NILP (retval) ? Qt : Qnil);
-
- return instantiator;
- }
- else
- abort (); /* Eh? */
-
- return Qunbound;
- }
-
- static int
- face_boolean_validate (Lisp_Object instantiator, int no_error)
- {
- if (NILP (instantiator) || EQ (instantiator, Qt))
- return 1;
- else if (VECTORP (instantiator) &&
- (XVECTOR (instantiator)->size == 2 ||
- XVECTOR (instantiator)->size == 3))
- {
- Lisp_Object face = vector_data (XVECTOR (instantiator))[0];
- Lisp_Object field = vector_data (XVECTOR (instantiator))[1];
-
- if (SYMBOLP (face))
- face = Ffind_face (face);
-
- if (!FACEP (face))
- return 0;
- else if (!EQ (field, Qunderline)
- && !EQ (field, Qhighlight)
- && !EQ (field, Qdim)
- && !EQ (field, Qblinking)
- && !EQ (field, Qreverse))
- return 0;
-
- return 1;
- }
- else
- return 0;
- }
-
- static void
- face_boolean_after_change (Lisp_Object specifier, Lisp_Object locale)
- {
- Lisp_Object face =
- FACE_BOOLEAN_SPECIFIER_FACE (XFACE_BOOLEAN_SPECIFIER (specifier));
- Lisp_Object property =
- FACE_BOOLEAN_SPECIFIER_FACE_PROPERTY (XFACE_BOOLEAN_SPECIFIER (specifier));
- if (!NILP (face))
- face_property_was_changed (face, property, locale);
- }
-
- void
- set_face_boolean_attached_to (Lisp_Object obj, Lisp_Object face,
- Lisp_Object property)
- {
- struct Lisp_Specifier *face_boolean = XFACE_BOOLEAN_SPECIFIER (obj);
-
- FACE_BOOLEAN_SPECIFIER_FACE (face_boolean) = face;
- FACE_BOOLEAN_SPECIFIER_FACE_PROPERTY (face_boolean) = property;
- }
-
- DEFUN ("face-boolean-specifier-p", Fface_boolean_specifier_p,
- Sface_boolean_specifier_p, 1, 1, 0,
- "Return non-nil if OBJECT is a face-boolean specifier.")
- (object)
- Lisp_Object object;
- {
- return (FACE_BOOLEAN_SPECIFIERP (object) ? Qt : Qnil);
- }
-
-
- /************************************************************************/
- /* initialization */
- /************************************************************************/
-
- void
- syms_of_objects (void)
- {
- defsubr (&Scolor_specifier_p);
- defsubr (&Sfont_specifier_p);
- defsubr (&Sface_boolean_specifier_p);
-
- defsymbol (&Qcolor_instancep, "color-instance-p");
- defsubr (&Smake_color_instance);
- defsubr (&Scolor_instance_p);
- defsubr (&Scolor_instance_name);
- defsubr (&Scolor_instance_rgb_components);
- defsubr (&Svalid_color_name_p);
-
- defsymbol (&Qfont_instancep, "font-instance-p");
- defsubr (&Smake_font_instance);
- defsubr (&Sfont_instance_p);
- defsubr (&Sfont_instance_name);
- defsubr (&Sfont_instance_truename);
- defsubr (&Sfont_instance_properties);
- defsubr (&Slist_fonts);
-
- /* Qcolor, Qfont defined in general.c */
- defsymbol (&Qface_boolean, "face-boolean");
- }
-
- void
- specifier_type_create_objects (void)
- {
- INITIALIZE_SPECIFIER_TYPE_WITH_DATA (color, "color", "color-specifier-p");
- INITIALIZE_SPECIFIER_TYPE_WITH_DATA (font, "font", "font-specifier-p");
- INITIALIZE_SPECIFIER_TYPE_WITH_DATA (face_boolean, "face-boolean",
- "face-boolean-specifier-p");
-
- SPECIFIER_HAS_METHOD (color, instantiate);
- SPECIFIER_HAS_METHOD (font, instantiate);
- SPECIFIER_HAS_METHOD (face_boolean, instantiate);
-
- SPECIFIER_HAS_METHOD (color, validate);
- SPECIFIER_HAS_METHOD (font, validate);
- SPECIFIER_HAS_METHOD (face_boolean, validate);
-
- SPECIFIER_HAS_METHOD (color, create);
- SPECIFIER_HAS_METHOD (font, create);
- SPECIFIER_HAS_METHOD (face_boolean, create);
-
- SPECIFIER_HAS_METHOD (color, mark);
- SPECIFIER_HAS_METHOD (font, mark);
- SPECIFIER_HAS_METHOD (face_boolean, mark);
-
- SPECIFIER_HAS_METHOD (color, after_change);
- SPECIFIER_HAS_METHOD (font, after_change);
- SPECIFIER_HAS_METHOD (face_boolean, after_change);
- }
-